package com.neusoft.neuiotms.dcom.config;

import java.util.Calendar;

import org.apache.commons.lang3.time.DateUtils;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.neusoft.bizcore.schedule.service.JobMgrService;
import com.neusoft.neuiotms.dcom.repository.HolidayRepository;
import com.neusoft.neuiotms.dcom.task.hn.HnReportTaskJob;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@EnableScheduling
public class ScheduledReportConfiguration {

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    @Autowired
    private JobMgrService jobMgrService;
    /** 日报提醒时间 */
    @Value("${business.notice.executionHour: 16}")
    private int noticeExecutionHour;
    @Autowired
    private HolidayRepository holidayRepository;

    // 每日凌晨1点，起动1~3个定时任务，报工提醒
    @Scheduled(cron = "0 0 1 * * ?")
    //@Scheduled(cron = "0 0 9 L * ?")
    //@Scheduled(cron = "0/5 * * * * ?")
    //@Scheduled(fixedRate = 30000000)
    public void run() {
        ScheduledReportConfiguration.log.info("scheduled to generate work report notice task every day.");

        final Calendar calendar = Calendar.getInstance();
        final String jobGroup = "REPORTNOTICE";
        // 计算当天的是周几
        final int today = (calendar.get(Calendar.DAY_OF_WEEK) - 1) == 0 ? 7 : calendar.get(Calendar.DAY_OF_WEEK) - 1;
        // 日报提醒暂时改为只依赖节假日设置。如果按照原自然日周一至周五判断，有可能漏掉国家调休的周六之类

        // if ((today >= 1) && (today <= 5) && (this.holidayRepository.findByDate(calendar.getTime()).size() == 0)) {
        if (this.holidayRepository.findByDate(DateUtils.round(calendar.getTime(), Calendar.DAY_OF_MONTH))
                .size() == 0) {
            ScheduledReportConfiguration.log.info("today is work day, will submit day report.");
            final String jobName = "DAILYREPORTNOTICE";
            this.genJob(jobName, jobGroup, ReportType.day);

        }

        if (today == 4) {
            ScheduledReportConfiguration.log.info("today is Thursday, will submit week report.");
            final String jobName = "WEEKLYREPORTNOTICE";
            this.genJob(jobName, jobGroup, ReportType.week);

        }

        if (calendar.get(Calendar.DAY_OF_MONTH) == 3) {
            ScheduledReportConfiguration.log.info("today is the 3th of month, will submit month report.");
            final String jobName = "MONTHREPORTNOTICE";
            this.genJob(jobName, jobGroup, ReportType.month);
        }
    }

    //    @Override
    //    protected void executeInternal(final JobExecutionContext context) throws JobExecutionException {
    //        final String typeStr = (String) context.getMergedJobDataMap().get("type");
    //        final ReportType type = ReportType.valueOf(typeStr);
    //        switch (type) {
    //        case day:
    //            this.workDailyService.checkDailyReportNotice();
    //            break;
    //        case week:
    //            this.operationSupportWeeklyService.checkReportNotice();
    //            break;
    //        case month:
    //            this.monthWeeklyService.checkReportNotice();
    //            break;
    //        default:
    //            break;
    //        }
    //    }

    private void genJob(final String jobName, final String jobGroup, final ReportType type) {

        final boolean existed = this.jobMgrService.isExists(jobName, jobGroup);
        if (!existed) {
            final JobDetail jobDetail =
                    JobBuilder.newJob(HnReportTaskJob.class).withIdentity(jobName, jobGroup)
                            .usingJobData("type", type.getValue())
                            .withDescription(jobName).build();
            final Calendar startAt = DateUtils.truncate(Calendar.getInstance(), Calendar.DAY_OF_MONTH);
            startAt.set(Calendar.HOUR_OF_DAY, this.noticeExecutionHour);
            final SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(jobName, jobGroup)
                    .startAt(startAt.getTime())
                    .withSchedule(
                            SimpleScheduleBuilder.simpleSchedule()
                                    .withIntervalInSeconds(3)
                                    .withRepeatCount(0))
                    .build();
            try {
                this.schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, simpleTrigger);
            } catch (final SchedulerException e) {
                ScheduledReportConfiguration.log.error("", e);
            }

        }
    }

    @Getter
    public enum ReportType {
        day("day"),
        week("week"),
        month("month");

        private final String value;

        ReportType(final String value) {
            this.value = value;
        }
    }
}
